YU-NO mestools
author: kingshriek
version: 1.8

mesdump.py       script (.MES) dumper
mesrebuild.py    script (.MES) rebuilder
messubs.py       substitution dictionary for mesrebuild.py

The tools only support the Windows (Elf Classics) release of the game.
All tools are Python 3.x scripts (they will not work with Python 2.x).
Feel free to contact me at either #tlwiki@irc.rizon.net or my tlwiki User 
Talk page (User:Kingshriek) regarding bugs/usage.



[SETUP/USAGE]



unpacking:

To unpack the script archive, use arcunpack.py in the YU-NO arctools package.
The archive containing the script files is named MES.ARC. Doing so should 
leave you with 903 script files.

To run:
    arcunpack.py -c <arc_file> <output_dir>


If that doesn't work out or is too slow to your liking, use crass 
(http://galcrass.blog124.fc2.com/). To unpack the archive, you must specify 
the AI5WIN cui plugin.

Specific command line:
    crage -p <path_to>\MES.ARC -u AI5WIN


dumping:

To dump the scripts, run mesdump.py on a directory containg the .MES files
that you want. mesdump.py will only process .MES files and ignore files with
other extensions in the directory. Scripts are currently dumped into two
separate files - bytecode dumps (.MSD extension) and text dumps (.MST
extension). Both files are utf-8 encoded (without BOM) text files.


Usage: mesdump.py [options] <input_dir> <output_dir>

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  process specific file named FILE (Unix-style wildcards
                        accepted, do not include file extension)
  -r REGEX, --regex=REGEX
                        filter processed files using REGEX (do not include
                        file extension)
  -R, --recurse         recurse through subdirectories
  -H, --half-recurse    recurse through subdirectories but leave output
                        directory flat
  -v, --verbose         verbose output



modifying:

The script dumps are separated into individual commands. Beside each command 
on the left is a label (ending with a ":") that identifies the command. 
Opcodes and most arguments are represented as hex digits. Command arguments 
that are interpreted as script offsets are converted to labels. Any strings 
occuring in the script data will appear in the dump as strings, surrounded 
by double-quote characters (""). Comments are indicated by beginning the line 
with //. Note: all comments must be entirely on their own line.

To make the script dumps look pleasant to the translator, the text commands
are separated out from the other script commands and are placed into .MST
files. The other bytecode commands are in corresponding .MSD files. This
prevents other script commands from being accidentally modified during the
translation process. This is a very good thing since mesrebuild.py does 
absolutely no checking on the integrity of the commands. Text in .MST files
are separated into pages, with #begin and #end statements surrounding each
"page" (line) of text. The .MSD files reference these page blocks with
#include statements.

Each text command in the .MST file is written out twice with the top one 
commented out. This is to help with translation by providing a reference to 
the original Japanese text. Also, the page block markers (#begin, #end)
surrounding the text aid in referring to a specific line during the 
translation/editing process. mesrebuild.py has basic support for 
word-wrapping and repagination, so you do not have to worry about the 
translated lines being too long for the text box. Don't worry about manually
changing bits of text that repeatedly appear throughout the script files
(such as the "who's speaking" tags). mesrebuild.py ues a global substitution
dictionary that performs all these changes during the rebuilding process. The
substitution dictionary is defined in messubs.py and should be straightforward
to edit.

Regarding text strings, everything within the very first and very last 
double-quote characters are passed directly to the rebuilt .MES file, with
exception of \protag or \newline. YU-NO lets you name your character at the 
beginning of the game and the script dumps use "\protag" in place of the 
command that reads the protaganist's name. \newline is the newline command. 
Additional double-quote characters within the very first and very last are 
passed to the script, so don't worry about them getting interpreted as 
syntax.

Word-wrapping should work with double-width characters as well, although this
hasn't been extensively tested. Also, there are a few sections of the game 
that have a NVL-like presentation instead of the usual ADV text box. 
mesrebuild.py does not detect this automatically. To handle these, use the 
#mode directive in the .MSD files right before the start of the NVL mode text.
Use #mode NVL to set NVL mode and #mode ADV to set it back to ADV mode after 
the last NVL text has been reached. An additional directive may be needed for
ero scenes - this will be added in a later version if this is the case.

The script dumps also allow for inserting additional commands. This can be 
done in either the .MSD or .MST files. You do not need a label for any 
commands unless you need to refer to it from another command which uses a 
script offset argument. If you do specify a label, there must be a space 
between the colon at the end of the label and the start of the command. It is
also ok to have a label all by itself on a single line. In this case, it will
refer to the next command that occurs after it. I'll repeat again that 
mesrebuild.py does absolutely no checking on the integrity/formatting of 
editted script commands, so excercise extreme caution when modifying scripting 
commands!




rebuilding:

To rebuild the modified scripts, run mesrebuild.py on the directory containing
them. mesrebuild.py will only process .MSD and .MST files and ignore files 
with other extensions in the directory.

Limited syntax error checking is performed on text commands and should be able
to catch most common problems. If a problem is encountered, processing will 
stop and the tool will display the error along with the file and line number.
Be warned, no such error checking is performed on non-text commands.

Also, at the top of the mesrebuild.py file is a global substitution 
dictionary, where you can put text that you want subsituted with something 
else during the rebuilding process. This is ideal for the "who's speaking"
tags (though not so much for anything else).


Usage: mesrebuild.py [options] <input_dir> <output_dir>

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  process specific file named FILE (Unix-style wildcards
                        accepted, do not include file extension)
  -r REGEX, --regex=REGEX
                        filter processed files using REGEX (do not include
                        file extension)
  -m, --make            only rebuild files not up to date
  -V VOICE_FILE, --voice=VOICE_FILE
                        voice patch the script using VOICE_FILE
  -R, --recurse         recurse through subdirectories
  -H, --half-recurse    recurse through subdirectories but leave output
                        directory flat
  -v, --verbose         verbose output




repacking:

Use arcrepack.py in the YU-NO arctools package on the directory containing 
the script files you want to pack.

To run:
    arcrepack.py -c <input_dir> arc_file

To change which .ARC file the game reads the script files from, change the
following entry in AI5WIN.INI (located where the game exe is), to the name
of what the new .ARC file is.

[FILE]
ARCMESNAME=

Interestingly, repacking is unnecessary as you can make the game read the
.MES files directly. In order to make this possible, you need to modify the
AI5WIN.INI file that is located wherever the game was installed. The changes
that need to be made are:

[FILE]
bARCMES=1 change to bARCMES=0

[MES]
bMES=1 change to bMESTYPE=0

This will modifiy the game's behavior to read the .MES files directly rather 
than unpacking them from an archive. Changing them back to their previous 
values will restore the original behavior (reading from MES.ARC archive).

Unfortunately, with this change, all of the .MES files must be in the same 
base directory as the game executable, whether they have been modified or
not. And with there being around 900 of them, it makes things a bit messy. I
haven't yet found out a way to get the game to read them from another
directory.



voice patch setup:

One neat application of being able to add additional commands to the script
dumps is that it is possible to transplant the voice files from the Saturn
version of the game. Doing so, however requires a bit of setup.

First, copy the VOICE.ABL files from each of the 3 Saturn discs. In order to 
extract and convert these into something which the Windows exe knows how to 
use, it will require some external tools.

Head to http://www.dsl.gr.jp/~sage/sagepage/prog/ and download the following
tools:

MCUT (mcut1101.lzh)
ACMCNV (acmcnv12.lzh)

First use MCUT on the VOICE.ABL files to generate a list of offsets/sizes
of all the voice data in the archives.

Specific command-line (w/ voice archive renamed to VOICE_A.ABL):
    MCUT -t aiff VOICE_A.ABL > <list_file>

After the list file has been generated, you can use ACMCNV to dump out
converted .wav files from the voice archive.

Here's how to do this:
    ACMCNV -C <output_dir> -l <list_file>
	
The ACMCNV tool will dump out 16-bit mono 18900 Hz PCM wav files. The
nonstandard sample rate used here is a bit of a problem, since the game
engine's sound effect command seems to play back at 22050 Hz no matter what. 
Therefore, resampling is necessary.

A convenient tool to do the resampling is SoX (http://sox.sourceforge.net/).

To resample an individual wav file, do:
    sox <input_wav> -r 22050 <output_wav>

You'll want to script this command over all the voice tracks. In the Windows
command shell, you can do this by:
    for %f in (*.wav) do sox %f -r 22050 <output_dir>\%f

Once the files are converted, place them somewhere within the game directory.
These will be played as sound commands so we need to have the game read the
files directly rather than from an archive. To do so, make the following
change to AI5WIN.INI:

[FILE]
bARCEFFECT=1 change to bARCEFFECT=0

Since we are no longer reading from EFFECT.ARC, use crass to extract the 
individual sound effect files in the same manner as MES.ARC. Copy the 
resulting .WAV files to the base game directory where the executable 
resides.

To have the game engine play the voice files, you need to place a sound
effect command before each of the relevant text commands.

The format of these sound commands is the following:
0D 05 FF 02 03 FF 01 "<path_to>\<wav_file>" 02 00 FF 00



voice patching:

To apply voice commands to .MST text dumps, run mesrebuild.py, simply
run mesrebuild.py using the --voice option, giving it the name of the
voice-mapping file. The voice file is not included in the tools package and 
needs to be supplied separately. The voice-mapping file is a mapping between 
the Saturn voice files and what pages of each .MST file they apply to. It 
consists of lines in the following format:

<script_name> <id> <archive> <saturn_id> <file_name> <page_number>

<script_name> refers to the name of the original script (.MES) file. <id> just 
refers to a running counter (starting at 1) of voices as they appeared in the
Saturn ver. scripts. <archive> refers to which voice archive the voice is
contained in (either VOICE_A, VOICE_B, VOICE_C - A,B,C referring to the 3 
discs of the Saturn game). <saturn_id> is the id string of the voice as it
occurs in the Saturn script files. It consists of a letter followed by a 
5-digit number - the letter refers to who is speaking. <file_name> is the name
of the particular .wav file for the voice if you dump the voice files
according to the above setup process. <page_number> refers to the page block
in the .MST file that the voice is to be applied to (this can be left blank in
the voices.txt file).

Currently, voice patching is setup so that there are 3 directories inside the 
folder where the game exe resides. These folders are named VOICE_A, VOICE_B,
and VOICE_C, each containing the .wav file dumps from the VOICE.ABL on Saturn
discs A, B, and C respectively.





[APPENDIX]



script file naming convention:

The general naming format of the scripts is: 
    <route>[_<subroute>]<location>[_<id>][<sub_id>][I].MES.

where fields enclosed in square brackets [] are optional.

<route> is one of the following:
    (none)    Mitsuki's route
    A         path to epilogue
    B         additional scripts (not really belonging to a particular route)
    C         Ayumi's route
    D         Mio's route
    E         Kanna's route
    F         Kaori's route
    P         prologue
    SP        special disk scenario
    Z         epilogue

<subroute> occurs only in Mio's route and the path to epilogue. It refers to 
scripts that pertain to a certain special location in the game (you probably 
know what I'm talking about if you've played it). Values can either be A, B, C 
for Mio's route (different branches) or (none) for the path to epilogue.

<location> is one of the following:
    01        protagonist's room
    02        living room
    03        Ayumi's room
    04        front of protagonist's house
    05        front of school gate
    06        school hall
    07        school 2nd floor
    08        school study room
    09        school infirmary
    10        school roof
    11        (not used)
    12        front of Mio's house
    13        Mio's room
    14        front of apartment building
    15        Kanna's room
    16        front of samurai residence
    17        samurai residence living room
    18        coast
    19        front of hotel
    20        hotel room
    21        central street
    22        shrine
    23        front of Kanna's room
    24        front of Geo-technics building
    25        cafe
    26        inside Geo-technics building
    27        heights
    28        park
    29        samurai residence garden
    30        well
    31        front of storehouse
    32        inside storehouse
    33        front of study door
    34        study
    35        empty study
    36        Geo-technics office
    37        Geo-technics lab

Locations 50 and above are used in the epilogue and special disk scenario.
To avoid potential (minor) spoilers, I will not detail these. Location numbers
for the <subroute> scripts mentioned above to not refer to the above list, but
instead refer to different locations within where the <subroute> scripts
take place.

<id> is there just to allow for multiple scripts per route/location 
combination. Typically, the <id>s go in chronological order along the route's
general timeflow. Scripts without and <id> typically serve as a base or 
default script for the route/location.

<sub_id> is a capital letter (starting with A) that can occur after the <id>.
I believe it is for variations among scripts that occur very close to 
one another chronologically for the particular route/location.

The I that can appear at the end of the script name is used to indicate 
scripts that contain the lines that are displayed when you use items. For
these, the route doesn't really matter so most of them are thrown in with the
Mitsuki script files (having no route letter).

Other script files that do not have the above format are usually for special
events/screens, i.e. opening, ending, map, menus, etc.



ini file tricks:

There's a few INI keys that you can add to the AI5WIN.INI to achieve various
effects.

[CONFIG]
; use font with name <string>
FONT=<string>        

[FILE]
; 0: disable CD check, 1: perform CD check
bCDROM=<bool>
